/**
 * @file 处理echart的数据, 使用方法参考generalView, 里面的echart使用了下面的方法.
 * @author hanzc
 * @date 2021-01-25
 */

import {userRoundIdx} from '~/utils/const';
import {ECHART_COLOR} from './color';

/** 后端的echartlist转换成map */
export const convertChartListToMap = chartUnit => {
    if (!Array.isArray(chartUnit)) {
        return {};
    }
    const chartMap = {};
    chartUnit.forEach(unit => {
        const {unitId, unitName, config, chart} = unit;
        if (!unitId && typeof unitId !== 'string') {
            return;
        }
        chartMap[unitId] = unit;
    });
    return chartMap;
};

/**
 * 合并前后端的echarts配置中, 合并xAxis和yAxis的方法
 * 先假设xy轴的配置是通用的, 写的通用的合并方法
 * @axisOptions 后端返回的echarts数据中的单个Axis的配置
 * @mergeAxisOptions 前端设置的echarts中的单个Axis的显示配置
 * @return 完整的单个axis的配置
 */
const mergeAxisEchartsOption = (axisOptions = [], mergeAxisOptions = {}) => {
    let resultAxisOptions = [];
    // 使用new就不用使用old了, 优先使用new
    const {
        newXAxis,
        newYAxis,
        oldXAxis,
        oldYAxis,
        common = {}
    } = mergeAxisOptions;
    if (Array.isArray(newXAxis) || Array.isArray(newYAxis)) {
        const newAxis = Array.isArray(newXAxis)
            ? newXAxis
            : Array.isArray(newYAxis)
                ? newYAxis
                : [];
        resultAxisOptions = newAxis.map(ele => {
            // common应用于全部Axis, 具体类型的配置具体类型
            if (typeof ele?.type === 'string' && mergeAxisOptions[ele?.type]) {
                return {
                    ...ele,
                    ...common,
                    ...(mergeAxisOptions[ele?.type] || {})
                };
            }
            return {...ele, ...common};
        });
    } else {
        resultAxisOptions = axisOptions.map(ele => {
            const oldAxis = Array.isArray(oldXAxis)
                ? oldXAxis
                : Array.isArray(oldYAxis)
                    ? oldYAxis
                    : [];
            if (Array.isArray(oldAxis)) {
                const usedAxis = oldAxis.find(
                    xaxis => xaxis?.name === ele?.name
                );
                if (usedAxis) {
                    ele = {...ele, ...usedAxis};
                }
            }
            // common应用于全部Axis, 具体类型的配置具体类型
            if (typeof ele?.type === 'string' && mergeAxisOptions[ele?.type]) {
                return {
                    ...ele,
                    ...common,
                    ...(mergeAxisOptions[ele?.type] || {})
                };
            }
            return {...ele, ...common};
        });
    }
    return resultAxisOptions;
};

/**
 * 合并前后端的echarts配置中, 合并echarts的series的方法
 * @series 后端返回的echarts数据中的series的配置
 * @seriesCfg 前端设置的echarts中的series的显示配置
 * @return 完整的series的配置
 */
const mergeSeriesEchartOption = (series = [], seriesCfg = {}) => {
    let resultSeries = [];
    const {newXAxis, newYAxis, common = {}} = seriesCfg;
    resultSeries = series.map(ele => {
        // 适配多x轴的情况
        if (Array.isArray(newXAxis)) {
            const usedXAxis = newXAxis.find(xaxis => xaxis?.name === ele?.name);
            if (usedXAxis) {
                ele = {...ele, ...usedXAxis};
            }
        }
        // 适配多y轴的情况
        if (Array.isArray(newYAxis)) {
            const usedYAxis = newYAxis.find(yaxis => yaxis?.name === ele?.name);
            if (usedYAxis) {
                ele = {...ele, ...usedYAxis};
            }
        }
        // common应用于全部series, 具体类型的配置具体类型
        if (typeof ele?.type === 'string' && seriesCfg[ele?.type]) {
            return {
                ...ele,
                ...common,
                ...(seriesCfg[ele?.type] || {})
            };
        }
        return {...ele, ...common};
    });
    return resultSeries;
};

/**
 * 合并前后端的echarts配置
 * @options 后端返回的echarts数据
 * @mergeOptions 前端设置的echarts显示配置
 * @return 完整的echarts配置
 */
export const mergeEchartsOption = (options = {}, mergeOptions = {}) => {
    // 无后缀的是原始的配置
    // 后缀为1的是要合并的配置
    // 后缀为2的是合并后的配置
    let {legend = {}, xAxis = [], yAxis = [], series = []} = options;
    const {
        title: title1 = {},
        tooltip: tooltip1 = {},
        legend: legend1 = {},
        revertXYAxis = false,
        xAxis: xAxisCfg = {},
        yAxis: yAxisCfg = {},
        series: seriesCfg = {},
        color: echartsColor = ECHART_COLOR,
        ...rest
    } = mergeOptions;

    // title
    const title2 = title1;
    // tooltip
    const tooltip2 = tooltip1;
    // legend
    const legend2 = {...legend, ...legend1};
    // swap xaxis and yaxis
    if (revertXYAxis) {
        [xAxis, yAxis] = [yAxis, xAxis];
    }
    // xaxis
    const xAxis2 = mergeAxisEchartsOption(xAxis, xAxisCfg);
    // yaxis
    const yAxis2 = mergeAxisEchartsOption(yAxis, yAxisCfg);
    // series
    const series2 = mergeSeriesEchartOption(series, seriesCfg);

    return {
        title: title2,
        color: echartsColor,
        tooltip: tooltip2,
        legend: legend2,
        xAxis: xAxis2,
        yAxis: yAxis2,
        series: series2,
        ...rest
    };
};

export const toLine = name => (name ? name.replace(/([A-Z])/g, '_$1').toLowerCase() : '');

/** 后端查询接口统一后, commonSearcher返回的参数就需要做转换了 */
export const convertSearcherParams = (params = {}, unitId) => {
    const dimensionAndValues = Object.entries(params)
        .map(([key = '', value = []]) => {
            if (Array.isArray(value)) {
                return {
                    dimensionId: unitId ? `${unitId}_${toLine(key)}` : toLine(key),
                    dimensionName: toLine(key),
                    value
                };
            }
            // 后端value只接收数组形式
            return {
                dimensionId: unitId ? `${unitId}_${toLine(key)}` : toLine(key),
                dimensionName: toLine(key),
                value: value == null ? [] : [value]
            };
        })
        .filter(({value} = {}) => value?.length > 0);
    if (!Array.isArray(dimensionAndValues)) {
        return [];
    }
    return dimensionAndValues;
};

export const strInsert = (str, length, insert) => {
    const text = str;
    const reg = new RegExp(`[^\\s]{1,${length}}`, 'g');
    const ma = text.match(reg);
    return ma ? ma.join(insert) : '';
};

/** 返回一个方法: 这个方法可以格式化antd rangePicker的值 */
export const formatRangePickerValue = (dateFormat = 'YYYY-MM-DD') => dateValue => {
    const [begin, end] = Array.isArray(dateValue) ? dateValue : [];
    const formattedDateValue = [
        begin?.format(dateFormat),
        end?.format(dateFormat)
    ];
    return formattedDateValue;
};

// table横向转纵向，只转数据，还用antd渲染
// 原列的长度 是新数据的长度；原数据的长度 是新列的长度
// 例子：春季续班-中心维度看板的table

/* index  默认第一列的数据为新的列 */
export const transformTableData = (columnList, value, index = 0) => {
    if (!columnList.length) {
        return [columnList, value];
    }

    const firstRowName = columnList?.[index]?.name;
    const newColumnList = [{name: firstRowName}];

    value.forEach(item => {
        newColumnList.push({
            name: item[firstRowName]
        });
    });

    const newValue = [];
    columnList.forEach((oldColumn, oldIdx) => {
        // 因为第一列数据作为新的列了，所以从第二列开始给新数据赋值
        if (oldIdx === 0) {
            return;
        }

        const oldName = oldColumn.name;
        const newValueItem = {};

        newColumnList.forEach((newColumn, newIdx) => {
            if (newIdx === 0) {
                newValueItem[firstRowName] = oldName;
            }
            else {
                const newName = newColumn.name;
                const oldValueItem = value.find(item => item[firstRowName] === newName);
                newValueItem[newName] = oldValueItem[oldName];
            }
        });

        newValue.push(newValueItem);
    });

    return [newColumnList, newValue];
};

/**
 * DimensionAndValues 添加did
 * @param {*} list
 * @param {*} dId
 */
export const parseDimensionAndValues = (list = [], dId = '') => {
    if (Array.isArray(list)) {
        return list.map(e => ({
            ...e,
            // 后加的需求tab切换，dimensionId固定，不是常规的 did + dimensionName
            dimensionId: (e.dimensionName === userRoundIdx ? e.dimensionId : `${dId}_${toLine(e.dimensionId)}`),
            dimensionName: toLine(e.dimensionName)
        }));
    }
    return list;
};

export const arrayColumnsTransform = (columns = [], data = []) => {
    const newColumns = [];
    const newValue = [];
    if (columns?.length > 0) {
        newColumns.push({
            id: columns[0].name,
            name: columns[0].name,
            dataIndex: columns[0].name,
            key: columns[0].name,
            title: columns[0].name,
            width: 150,
            fixed: 'left'
        });
        for (let j = 1; j < columns.length; j++) {
            const addObj = {
                [columns[0].name]: columns[j].name
            };
            for (let k = 0; k < data.length; k++) {
                addObj[data[k][columns[0].name]] = data[k][columns[j].name];
            }
            newValue.push(addObj);
        }
        for (let i = 0; i < data.length; i++) {
            newColumns.push({
                id: data[i][columns[0].name],
                name: data[i][columns[0].name],
                dataIndex: data[i][columns[0].name],
                key: data[i][columns[0].name],
                title: data[i][columns[0].name],
                width: 100
            });
        }
    }
    return {newColumnList: newColumns, newData: newValue};
};
